#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_ttf.h>
#include <exception>
#include "Input.hpp"
#include <iostream>
#include "LevelGrid.hpp"
#include "Projectile.hpp"
#include "TestArrow.hpp"
#include "Timer.hpp"
#include "TowerDefense.hpp"
#include "Vector.hpp"

void TowerDefense::_InitializeAllegro()
{
	// No allegro functions can be called before this one.
	if(!al_init())
		throw std::exception("Allegro initialization failed.");

	_display.reset(al_create_display(512, 512), [](ALLEGRO_DISPLAY* p){al_destroy_display(p);});

	if(!al_install_keyboard())
		throw std::exception("Failed to install keyboard driver.");

	if(!al_install_mouse())
		throw std::exception("Failed to install mouse driver.");

	// The order in which these functions are called is important. DO NOT CHANGE IT!
	al_init_font_addon();
	al_init_ttf_addon();

	if(!al_init_image_addon())
		throw std::exception("Failed to initialize the image addons.");
}

TowerDefense::TowerDefense()
{
	_InitializeAllegro();

	_timer.reset(new Timer());
	_input.reset(new Input());
	_test_arrow.reset(new TestArrow(Vector(256.0f, 256.0f)));
	_level_grid.reset(new LevelGrid());
}

TowerDefense::~TowerDefense()
{
	Projectile::CleanUpProjectiles();
}

int TowerDefense::Run()
{
	try
	{
		bool run_game(true);
		while(run_game)
		{
			_timer->Update();
			_input->PollInputDevices();
			_UpdateScene(_timer->GetDT());
			_DrawScene();

			if(_input->IsKeyPressed(ALLEGRO_KEY_ESCAPE))
				run_game = false;
		}

		return 0;
	}
	catch(const std::exception& e)
	{
		std::cerr << "An exception occurred: " << e.what() << std::endl;
	}
	return -1;
}